import * as Type from './type'

const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice

export function promisify(func) {
  if (!Type.isFunction(func)) return func
  return (args = {}) => new Promise((resolve, reject) => {
    func(
      Object.assign(args, {
        success: resolve,
        fail: reject
      })
    )
  })
}

export function addParams(url = '', params = {}) {
  const parts = url.split('?')
  const query = Object.keys(params).map(key => `${key}=${params[key]}`).join('&')
  return query ? `${parts[0]}?${query}` : parts[0]
}

export const awaitWrap = (promise) => promise
  .then(data => [null, data])
  .catch(err => [err, null])

export function readFileAsyn(params) {
  // eslint-disable-next-line prefer-const
  let {file, position, length} = params
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader()
    fileReader.onload = (event) => {
      resolve(event.target.result)
    }
    fileReader.onerror = (event) => {
      reject(event)
    }
    position = position || 0
    length = length || file.size
    fileReader.readAsArrayBuffer(blobSlice.call(file, position, position + length))
  })
}

/**
 * Use Object.prototype.toString
 * @param {Any} obj
 * @return {String}
 */
export const toString = (obj) => Object.prototype.toString.call(obj)

/**
 * Extend the object
 * @param {Object} target
 * @param {Object} source
 * @return {Object}
 */
export const extend = (target, options) => {
  target = target || {}
  options = options || {}
  Object.keys(options).forEach((key) => {
    const value1 = target[key]
    const value2 = options[key]
    if (Type.isArray(value2)) {
      target[key] = extend(value1 || [], value2)
    } else if (Type.isObject(value2)) {
      target[key] = extend(value1 || {}, value2)
    } else if (toString(value1) === toString(value2)) {
      target[key] = value1
    } else {
      target[key] = value2
    }
  })
  return target
}
